/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#ifndef GLDISPLAY_H
#define GLDISPLAY_H

#include <wx/wx.h>
#include <wx/glcanvas.h>
//#include "Core.hpp"
#include "thread.hpp"
#include "picking/picking.hpp"



/*
GLCanvas to be used in Opengl-drawing
*/

#define CLEAR_COLOR         0.0,0.0,0.0
//#define CLEAR_COLOR         0.2,0.2,0.2

#define GRID_COLOR          0.0,0.5,0.0
#define GRID_LINE_WIDTH     1
#define AXIS_COLOR          0.5,0.0,0.0

#define MAP_COLOR           0.2,0.5,0.8
#define MAP_LINE_WIDTH      2

#define SCALE_MAX           300
#define SCALE_MIN           10

#define THROTTLE_PER_CENT_DELTA 5

class MuRoMainFrame;

namespace MuRo
{

class CMachine;

/*enum EDisplayType
{
  KBigView = 1,
  KMiniView = 2
};

enum ERenderMode
{
  KRenderMode2D = 2,
  KRenderMode3D = 3
};*/

// enum EOperationMode
// {
//   KOperModeManualDrive = 1,
//   KOperModeCoordDrive = 2,
//   KOperModeSetPosition = 3
//   //KOperModeMapEdit = 4, etc...
// };

struct TViewParams
{
  //EDisplayType displayType;
  //ERenderMode renderMode;
  int Scale; //pixels per meter
  float Left, Right, Top, Bottom; //view bounds in 2d
  float OriginX, OriginY; //view center point in 2d
  int Width, Height; //view dimensions in pixels
};
  
class CGLDisplay : public wxGLCanvas, 
                   public CGLPickable, 
                   public CGLPickingContext, 
                   public CGLPickCallback,
                   private gim::CThread//, private gim::CSync
{
  DECLARE_EVENT_TABLE()
  public:
    CGLDisplay(wxWindow* parent, MuRoMainFrame* mainFrame);

    ~CGLDisplay();
    
    void OnPaint(wxPaintEvent &e);
    void OnSize(wxSizeEvent &e);
    void OnErase(wxEraseEvent &e);
    void OnLeftDown(wxMouseEvent &e);
    void OnLeftUp(wxMouseEvent &e);
    void OnDoubleClick(wxMouseEvent &e);
    void OnRightDown(wxMouseEvent &e);
    void OnRightUp(wxMouseEvent &e);
    void OnMotion(wxMouseEvent &e);
    void OnMouseWheel(wxMouseEvent &e);
    void OnLeaveWindow(wxMouseEvent &e);
    void OnChar(wxKeyEvent &e);
    void OnKeyDown(wxKeyEvent &e);
    void OnKeyUp(wxKeyEvent &e);
    //void OnContextMenu(wxContextMenuEvent &e);
    
    /** Set follow mode
     * 
     * In follow mode, camera will be fixed to currently selected machine.
     */
    void SetFollowMode(bool follow);
    
    void SetGrid(bool grid);
    
//     void SetOperationMode(EOperationMode mode);
    
    
    
    static int attribList[];

    const TViewParams& GetViewParams();
    
    /* picking stuff */
    void OnPick(TGLPickEvent event);
    
    void OnDrag(TGLPickEvent event);
    
    //draw the layer that is beneath other pickable objects. only drag events to
    //this layer will cause the view to be dragged
    void DrawPickable();
    
    void CenterToSelected();
    
    void Zoom(float x, float y, int scale);
    
    void ZoomIn();
    void ZoomOut();
    
  private:
    MuRoMainFrame *mainFrame;
    
    
    wxGLContext GLContext;
        
    bool followSelected;
    
    //EOperationMode operationMode;
    
    //grid params
    bool grid;
    float gridZ;
    float gridSize;
    
    /**2d view params**/
    TViewParams view;

    int mouseClickX, mouseClickY; //location of last click on screen
    
    /**3d view params**/
    //nothing yet
    
    /** driving params */
    float throttle;
    bool keyUp, keyDown, keyRight, keyLeft, keyBoost; //what keys are pressed
    bool driving;
    
    /** position setting mode params */
    float posSetX,posSetY;
    float posSetHeading;
    
    bool picked; //set to true every time picking happens
    bool contextMenuOnMachine;
    
    bool editingPath;
    
    void setView();
    void draw();
    void drawGrid();
    void drawMachines();
    void drawHUD();
    
    
    void handleArrowKeys();
    
    int ThreadFunction(const int aThreadNumber);
    
    void centerToSelected();
};

}

#endif
